/**
 * Copyright 2018 jianggujin (www.jianggujin.com).
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *      http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.jianggujin.modulelink.mvc.render;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.jianggujin.modulelink.mvc.JActionContext;
import com.jianggujin.modulelink.mvc.render.JRedirectRender.JRedirectRenderParam;
import com.jianggujin.modulelink.util.JAssert;

/**
 * 重定向渲染
 * 
 * @author jianggujin
 *
 */
public class JRedirectRender implements JRender<JRedirectRenderParam> {

   @Override
   public void render(JActionContext context, JRedirectRenderParam param) throws IOException, ServletException {
      JAssert.checkNotNull(context, "context must not be null");
      JAssert.checkNotNull(param, "param must not be null");
      HttpServletRequest request = context.getRequest();
      HttpServletResponse response = context.getResponse();

      String finalUrl = buildFinalUrl(request, param.getUrl(), param.isWithQueryString());

      // 支持 https 协议下的重定向
      if (!finalUrl.startsWith("http")) { // 跳过 http/https 已指定过协议类型的 url
         if (request.getScheme().equals("https")) {
            if (finalUrl.charAt(0) != '/') {
               finalUrl = "https://" + request.getServerName() + "/" + finalUrl;
            } else {
               finalUrl = "https://" + request.getServerName() + finalUrl;
            }
         }
      }
      response.sendRedirect(finalUrl); // always 302
   }

   protected String buildFinalUrl(HttpServletRequest request, String url, boolean withQueryString) {
      String result;
      String contextPath = request.getContextPath();
      contextPath = ("".equals(contextPath) || "/".equals(contextPath)) ? null : contextPath;
      // 如果一个url为/login/connect?goto=http://www.jianggujin.com，则有错误
      // ^((https|http|ftp|rtsp|mms)?://)$ ==> indexOf 取值为 (3, 5)
      if (contextPath != null && (url.indexOf("://") == -1 || url.indexOf("://") > 5)) {
         result = contextPath + url;
      } else {
         result = url;
      }

      if (withQueryString) {
         String queryString = request.getQueryString();
         if (queryString != null) {
            if (result.indexOf('?') == -1) {
               result = result + "?" + queryString;
            } else {
               result = result + "&" + queryString;
            }
         }
      }

      return result;
   }

   public static class JRedirectRenderParam {
      private final String url;
      private boolean withQueryString;

      public JRedirectRenderParam(String url) {
         JAssert.checkNotNull(url, "url must not be null.");
         this.url = url;
      }

      public String getUrl() {
         return url;
      }

      public boolean isWithQueryString() {
         return withQueryString;
      }

      public void setWithQueryString(boolean withQueryString) {
         this.withQueryString = withQueryString;
      }
   }

}
